package org.web.base.helper.excel;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import java.io.IOException;

public class ExcelOperatorHelper {

    /**
     * 将源工作表的数据和样式复制到目标工作表
     * @param sourceSheet 源工作表
     * @param targetSheet 目标工作表
     */
    public static void copySheet(Sheet sourceSheet, Sheet targetSheet) {
        if (sourceSheet == null || targetSheet == null) {
            throw new IllegalArgumentException("源工作表和目标工作表不能为null");
        }

        Workbook targetWorkbook = targetSheet.getWorkbook();
        Workbook sourceWorkbook = sourceSheet.getWorkbook();

        // 复制合并单元格
        copyMergedRegions(sourceSheet, targetSheet);

        // 复制行数据和样式
        int rowCount = sourceSheet.getLastRowNum();
        for (int i = 0; i <= rowCount; i++) {
            Row sourceRow = sourceSheet.getRow(i);
            if (sourceRow != null) {
                copyRow(sourceWorkbook, targetWorkbook, sourceSheet, targetSheet, sourceRow, i);
            }
        }

        // 复制列宽
        copyColumnWidths(sourceSheet, targetSheet);
    }

    /**
     * 复制合并单元格区域
     */
    private static void copyMergedRegions(Sheet sourceSheet, Sheet targetSheet) {
        int mergedRegionCount = sourceSheet.getNumMergedRegions();
        for (int i = 0; i < mergedRegionCount; i++) {
            CellRangeAddress mergedRegion = sourceSheet.getMergedRegion(i);
            targetSheet.addMergedRegion(mergedRegion);
        }
    }

    /**
     * 复制单行数据和样式
     */
    private static void copyRow(Workbook sourceWorkbook, Workbook targetWorkbook,
                                Sheet sourceSheet, Sheet targetSheet,
                                Row sourceRow, int rowIndex) {
        Row targetRow = targetSheet.createRow(rowIndex);
        targetRow.setHeight(sourceRow.getHeight());

        // 复制单元格
        int cellCount = sourceRow.getLastCellNum();
        for (int i = 0; i < cellCount; i++) {
            Cell sourceCell = sourceRow.getCell(i);
            if (sourceCell != null) {
                Cell targetCell = targetRow.createCell(i);
                copyCell(sourceWorkbook, targetWorkbook, sourceCell, targetCell);
            }
        }
    }

    /**
     * 复制单个单元格的数据和样式
     */
    private static void copyCell(Workbook sourceWorkbook, Workbook targetWorkbook,
                                 Cell sourceCell, Cell targetCell) {
        // 复制单元格样式
        CellStyle sourceStyle = sourceCell.getCellStyle();
        CellStyle targetStyle = targetWorkbook.createCellStyle();
        targetStyle.cloneStyleFrom(sourceStyle);
        targetCell.setCellStyle(targetStyle);

        // 复制单元格数据
        switch (sourceCell.getCellType()) {
            case STRING:
                targetCell.setCellValue(sourceCell.getStringCellValue());
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(sourceCell)) {
                    targetCell.setCellValue(sourceCell.getDateCellValue());
                } else {
                    targetCell.setCellValue(sourceCell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                targetCell.setCellValue(sourceCell.getBooleanCellValue());
                break;
            case FORMULA:
                targetCell.setCellFormula(sourceCell.getCellFormula());
                break;
            case BLANK:
                targetCell.setBlank();
                break;
            default:
                targetCell.setCellValue(sourceCell.getStringCellValue());
        }
    }

    /**
     * 复制列宽设置
     */
    private static void copyColumnWidths(Sheet sourceSheet, Sheet targetSheet) {
        int columnCount = sourceSheet.getRow(0).getLastCellNum();
        for (int i = 0; i < columnCount; i++) {
            targetSheet.setColumnWidth(i, sourceSheet.getColumnWidth(i));
        }
    }

    /**
     * 关闭工作簿
     */
    public static void closeWorkbook(Workbook workbook) {
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                System.err.println("关闭工作簿时发生错误: " + e.getMessage());
            }
        }
    }
}
